package com.js.admin.controller;

import com.js.admin.constant.AdminConstant;
import com.js.admin.entity.BaseElement;
import com.js.admin.entity.BaseGroup;
import com.js.admin.service.BaseGroupService;
import com.js.admin.service.BaseResourceAuthorityService;
import com.js.admin.vo.AuthorityMenuTree;
import com.js.admin.vo.GroupTree;
import com.js.admin.vo.GroupUsers;
import com.js.admin.vo.MenuTree;
import com.js.auth.client.annotation.CheckUserToken;
import com.js.common.controller.BaseController;
import com.js.common.response.ObjectRestResponse;
import com.js.common.response.TableResultResponse;
import com.js.common.util.TreeUtil;
import com.js.core.context.BaseContextHandler;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.List;

/**
 * @author： ygl
 * @date： 2018/11/01-17:03
 * @Description：
 */
@CheckUserToken
@Api(tags = {"角色模块"})
@RestController
@RequestMapping("/group")
public class BaseGroupController extends BaseController<BaseGroup,String>{

    @Autowired
    private BaseGroupService baseGroupService;

    @Autowired
    private BaseResourceAuthorityService baseResourceAuthorityService;

    @GetMapping("/list")
    public List<BaseGroup> list(String name, String groupType) {
        if (StringUtils.isBlank(name) && StringUtils.isBlank(groupType)) {
            return new ArrayList<BaseGroup>();
        }
        Example example = new Example(BaseGroup.class);
        if (StringUtils.isNotBlank(name)) {
            example.createCriteria().andLike("name", "%" + name + "%");
        }
        if (StringUtils.isNotBlank(groupType)) {
            example.createCriteria().andEqualTo("groupType", groupType);
        }

        return baseGroupService.selectByExample(example);
    }

    @ApiOperation("用户关联角色")
    @PutMapping("/{id}/user")
    public ObjectRestResponse modifiyUsers(@PathVariable String id, String members, String leaders) {
        baseGroupService.modifyGroupUsers(id, members, leaders);
        return new ObjectRestResponse();
    }

    @ApiOperation("获取角色关联用户")
    @RequestMapping(value = "/{id}/user", method = RequestMethod.GET)
    @ResponseBody
    public ObjectRestResponse<GroupUsers> getUsers(@PathVariable String id) {
        return new ObjectRestResponse<GroupUsers>().data(baseGroupService.getGroupUsers(id));
    }

    @ApiOperation("分配角色可访问菜单")
    @RequestMapping(value = "/{id}/authority/menu", method = RequestMethod.POST)
    @ResponseBody
    public ObjectRestResponse modifyMenuAuthority(@PathVariable String id, String menuTrees) {
        String[] menus = menuTrees.split(",");
        baseGroupService.modifyAuthorityMenu(id, menus, AdminConstant.RESOURCE_TYPE_VIEW);
        return new ObjectRestResponse();
    }

    @ApiOperation("获取角色可访问菜单")
    @RequestMapping(value = "/{id}/authority/menu", method = RequestMethod.GET)
    @ResponseBody
    public ObjectRestResponse<List<AuthorityMenuTree>> getMenuAuthority(@PathVariable String id) {
        return new ObjectRestResponse().data(baseGroupService.getAuthorityMenu(id, AdminConstant.RESOURCE_TYPE_VIEW));
    }

    @ApiOperation("角色分配菜单可访问资源")
    @RequestMapping(value = "/{id}/authority/element/add", method = RequestMethod.POST)
    @ResponseBody
    public ObjectRestResponse addElementAuthority(@PathVariable String id, String menuId, String elementId) {
        baseGroupService.modifyAuthorityElement(id, menuId, elementId, AdminConstant.RESOURCE_TYPE_VIEW);
        return new ObjectRestResponse();
    }

    @ApiOperation("角色移除菜单可访问资源")
    @RequestMapping(value = "/{id}/authority/element/remove", method = RequestMethod.POST)
    @ResponseBody
    public ObjectRestResponse removeElementAuthority(@PathVariable String id, String menuId, String elementId) {
        baseGroupService.removeAuthorityElement(id, elementId, AdminConstant.RESOURCE_TYPE_VIEW);
        return new ObjectRestResponse();
    }

    @ApiOperation("获取角色可访问资源")
    @RequestMapping(value = "/{id}/authority/element", method = RequestMethod.GET)
    @ResponseBody
    public ObjectRestResponse<List<String>> getElementAuthority(@PathVariable String id) {
        return new ObjectRestResponse().data(baseGroupService.getAuthorityElement(id, AdminConstant.RESOURCE_TYPE_VIEW));
    }

    @ApiOperation("分配角色可授权菜单")
    @RequestMapping(value = "/{id}/authorize/menu", method = RequestMethod.POST)
    @ResponseBody
    public ObjectRestResponse modifyMenuAuthorize(@PathVariable String id, String menuTrees) {
        String[] menus = menuTrees.split(",");
        baseGroupService.modifyAuthorityMenu(id, menus, AdminConstant.RESOURCE_TYPE_AUTHORISE);
        return new ObjectRestResponse();
    }

    @ApiOperation("获取角色可授权菜单")
    @RequestMapping(value = "/{id}/authorize/menu", method = RequestMethod.GET)
    @ResponseBody
    public ObjectRestResponse<List<AuthorityMenuTree>> getMenuAuthorize(@PathVariable String id) {
        return new ObjectRestResponse().data(baseGroupService.getAuthorityMenu(id, AdminConstant.RESOURCE_TYPE_AUTHORISE));
    }

    @ApiOperation("角色分配菜单可授权资源")
    @RequestMapping(value = "/{id}/authorize/element/add", method = RequestMethod.POST)
    @ResponseBody
    public ObjectRestResponse addElementAuthorize(@PathVariable String id, String menuId, String elementId) {
        baseGroupService.modifyAuthorityElement(id, menuId, elementId, AdminConstant.RESOURCE_TYPE_AUTHORISE);
        return new ObjectRestResponse();
    }

    @ApiOperation("角色移除菜单可授权资源")
    @RequestMapping(value = "/{id}/authorize/element/remove", method = RequestMethod.POST)
    @ResponseBody
    public ObjectRestResponse removeElementAuthorize(@PathVariable String id, String menuId, String elementId) {
        baseGroupService.removeAuthorityElement(id, elementId, AdminConstant.RESOURCE_TYPE_AUTHORISE);
        return new ObjectRestResponse();
    }

    @ApiOperation("获取角色可授权资源")
    @RequestMapping(value = "/{id}/authorize/element", method = RequestMethod.GET)
    @ResponseBody
    public ObjectRestResponse<List<String>> getElementAuthorize(@PathVariable String id) {
        return new ObjectRestResponse().data(baseGroupService.getAuthorityElement(id, AdminConstant.RESOURCE_TYPE_AUTHORISE));
    }

    @ApiOperation("获取角色树")
    @RequestMapping(value = "/tree", method = RequestMethod.GET)
    @ResponseBody
    public List<GroupTree> tree(String name, String groupType) {
        Example example = new Example(BaseGroup.class);
        if (StringUtils.isNotBlank(name)) {
            example.createCriteria().andLike("name", "%" + name + "%");
        }
        if (StringUtils.isNotBlank(groupType)) {
            example.createCriteria().andEqualTo("groupType", groupType);
        }
        return getTree(baseGroupService.selectByExample(example), AdminConstant.ROOT);
    }

    /**
     * 获取可管理的资源
     * @param menuId
     * @return
     */
    @ApiOperation("获取用户可管理资源")
    @RequestMapping(value = "/element/authorize/list", method = RequestMethod.GET)
    public TableResultResponse<BaseElement> getAuthorizeElement(String menuId) {
        List<BaseElement> elements = baseGroupService.getAuthorizeElements(menuId);
        return new TableResultResponse<BaseElement>(elements.size(), elements);
    }

    /**
     * 获取可管理的菜单
     * @return
     */
    @ApiOperation("获取用户可管理菜单")
    @GetMapping("/menu/authorize/list")
    public List<MenuTree> getAuthorizeMenus() {
        List<MenuTree> authorizeMenus = baseGroupService.getAuthorizeMenus(BaseContextHandler.getUserId(), BaseContextHandler.getClientId());
        return TreeUtil.bulid(authorizeMenus, AdminConstant.ROOT, null);
    }

    private List<GroupTree> getTree(List<BaseGroup> groups, String root) {
        List<GroupTree> trees = new ArrayList<GroupTree>();
        GroupTree node = null;
        for (BaseGroup group : groups) {
            node = new GroupTree();
            node.setLabel(group.getName());
            BeanUtils.copyProperties(group, node);
            trees.add(node);
        }
        return TreeUtil.bulid(trees, root, null);
    }

}
